package handler

import (
	"fmt"
	"choujiang/box_server/service"
	"choujiang/common/consts"
	"choujiang/common/models"
	"choujiang/common/utils"
	"time"

	"io/ioutil"
	"net/http"
	"os"

	"encoding/base64"
	"github.com/gin-gonic/gin"
	"choujiang/common/db"
	"choujiang/common/variable"
	"strconv"
)

const (
	FILE_PATH     = "/root/1RD2qrlGAz.txt"
	NEW_FILE_PATH = "/root/CDXZ09fSxy.txt"
)

type CodeApiUserResp struct {
	UniqueId string `json:"uniqueId"`
	OpenId   string `json:"openId"`
	IsNew    int    `json:"isNew"`
}

type RespUser struct {
	UserId     int64  `json:"userId"`
	UniqueId   string `json:"uniqueId"`
	OpenId     string `json:"openId"`
	NickName   string `json:"nickName"`
	HeadImgUrl string `json:"headImgUrl"`
}

func Code(c *gin.Context) {
	form := c.Request.Form
	code := form.Get("code")
	gameId := form.Get("gameId")
	fmt.Printf("code:%s\n", code)

	if gameId == "" {
		gameId = "leyoubox"
	}
	if _, ok := variable.EntryBoxs[gameId]; !ok {
		utils.Error(consts.ErrUndefinedEntry, c)
		return
	}
	boxEntry := variable.EntryBoxs[gameId]
	loginInfo, err := service.CodeToUserInfo(code, &boxEntry)
	if err != nil {
		fmt.Printf("err is ----------%s", err)
		utils.Error(consts.ErrInvalidParams, c)
		return
	}

	if loginInfo.OpenId == "" {
		utils.Error(consts.ErrInvalidParams, c)
		return
	}
	user := new(model.User)
	userGameOpenid := model.GetUserGameOpenid(gameId, loginInfo.OpenId)
	fmt.Printf("userGameOpenid is %v \n", userGameOpenid)
	if userGameOpenid != nil {
		user = model.GetUserByUid(userGameOpenid.UserId)
		fmt.Printf("user by GetUserByUid is %v \n", user)
	} else {
		if loginInfo.UnionID != "" {
			user = model.GetUserByMiniProgramUnionId(loginInfo.UnionID)
			fmt.Printf("user by GetUserByMiniProgramUnionId is %v \n", user)
		} else {
			user = model.GetUserByMiniOpenId(loginInfo.OpenId)
		}
	}
	isNew := 0

	//保存session key
	if err = service.SetUserSessionKey(loginInfo.OpenId, gameId, loginInfo.SessionKey); err != nil {
		fmt.Printf("SetUserSessionKey err : %+v\n", err)
	}

	if user != nil {
		isNew = 1
		resp := &CodeApiUserResp{
			UniqueId: user.UniqueId,
			OpenId:   loginInfo.OpenId,
			IsNew:    isNew,
		}
		utils.JSON(resp, c)
	} else {
		resp := &CodeApiUserResp{
			OpenId: loginInfo.OpenId,
			IsNew:  isNew,
		}
		utils.JSON(resp, c)
	}
}

func SetUserInfo(c *gin.Context) {
	form := c.Request.Form
	iv := form.Get("iv")
	openId := form.Get("openId")
	encryptedData := form.Get("encryptedData")
	gameId := form.Get("gameId")
	token := form.Get("share_token")        //分享token
	fromChannel := form.Get("from_channel") //渠道来源
	scene := form.Get("scene")              //scene
	fmt.Printf("gameId : %s, openId: %s, encryptedData: %s, iv: %s\n", gameId, openId, encryptedData, iv)
	if openId == "" || encryptedData == "" || iv == "" || gameId == "" {
		utils.Error(consts.ErrInvalidParams, c)
		return
	}
	newUserInfo, err := service.ParseUserInfo(openId, gameId, encryptedData, iv, nil, "")
	if err != nil {
		fmt.Printf("newUserInfo err: %+v\n", err)
		utils.Error(consts.ErrMiniOriData, c)
		return
	}
	user := model.GetUserByMiniUnionId(newUserInfo.UnionID)
	if user == nil { //无法通过unionid找到同主体下的同一个用户，是新的用户
		reInt, shareStruct := service.ValidateShareToken(token)
		var parentId int64
		if reInt != 0 { //shareToken验证成功，用户通过其他用户的分享连接进入
			parentId = shareStruct.UserId
			parentUser := model.GetUserByUid(parentId)
			if parentUser.FromChannel != "" {
				fromChannel = parentUser.FromChannel
			}
			goods := model.GetGoodsById(shareStruct.GoodsId)
			if goods != nil { //分享新用户成功，获取抽奖券
				go func() {
					service.CreateInviteCoupon(shareStruct.UserId, goods)
				}()
			}
		} else { //shareToken验证失败
			if scene != "" { //scene不为空，用户通过二维码进入
				parentId = db.Mgo.GetUserIdFromScene(scene)
				if parentId != 0 {
					parentUser := model.GetUserByUid(parentId)
					fmt.Printf("分享二维码的用户是 %v \n", parentUser)
					if parentUser.FromChannel != "" {
						fromChannel = parentUser.FromChannel
					}
					//判断是否有商品id，是否可以领取券码
					goodsId := db.Mgo.GetGoodsIdFromScene(scene)
					goods := model.GetGoodsById(goodsId)
					if goods != nil { //分享新用户成功，获取抽奖券
						go func() {
							service.CreateInviteCoupon(parentId, goods)
						}()
					}
				}
			}
		}
		if fromChannel == "" {
			fromChannel = "leyouguanfang"
		}
		newUser := &model.User{
			UniqueId:         utils.GenUid("leyoubox", newUserInfo.OpenId),
			MiniOpenId:       newUserInfo.OpenId,
			MiniUnionId:      newUserInfo.UnionID,
			GameId:           gameId,
			ShareCode:        utils.GenUid("leyoubox_shareCode", newUserInfo.OpenId),
			City:             newUserInfo.City,
			Province:         newUserInfo.Province,
			HeadImgUrl:       newUserInfo.AvatarURL,
			Sex:              newUserInfo.Gender,
			NickName:         base64.StdEncoding.EncodeToString([]byte(newUserInfo.NickName)),
			HeadImgUpdatedAt: time.Now().Unix(),
			FromChannel:      fromChannel,
		}
		if user, err = newUser.Insert(); err != nil {
			fmt.Printf("err %+v\n", err)
		}
		userExtra := &model.UserExtra{
			Point:    model.INIT_POINT,
			Balance:  model.INIT_BALANCE,
			UserId:   user.Id,
			ParentId: parentId,
		}
		if _, err := userExtra.Insert(); err != nil {
			fmt.Printf("err %+v\n", err)
		}
		//记录渠道新增用户
		go db.Mgo.RecordPlayUser(fromChannel)
	} else { //找到了同一个用户是旧用户
		user.City = newUserInfo.City
		user.Province = newUserInfo.Province
		user.HeadImgUrl = newUserInfo.AvatarURL
		user.Sex = newUserInfo.Gender
		user.NickName = base64.StdEncoding.EncodeToString([]byte(newUserInfo.NickName))
		user.HeadImgUpdatedAt = time.Now().Unix()
		_, err := user.Update()
		if err != nil {
			utils.Error(consts.ErrUserUpadteFail, c)
			return
		}
	}
	userGameOpenid := model.GetUserGameOpenid(gameId, openId)
	if userGameOpenid == nil { //还没保存过用户和这个盒子的对应关系
		ugo := &model.UserGameOpenid{
			GameId:      gameId,
			MiniOpenId:  newUserInfo.OpenId,
			MiniUnionId: newUserInfo.UnionID,
			UserId:      user.Id,
		}
		if _, err := ugo.Insert(); err != nil {
			fmt.Printf("err %+v\n", err)
		}
	}
	resp := &RespUser{
		UserId:     user.Id,
		OpenId:     newUserInfo.OpenId,
		UniqueId:   user.UniqueId,
		NickName:   newUserInfo.NickName,
		HeadImgUrl: newUserInfo.AvatarURL,
	}
	utils.JSON(resp, c)
}

//CodeHandler: 用户登录注册
func CodeHandler(c *gin.Context) {
	var parentId int64
	form := c.Request.Form
	code := form.Get("code")
	gameId := form.Get("gameId")
	iv := form.Get("iv")
	encryptedData := form.Get("encryptedData")
	token := form.Get("share_token") //分享token
	scene := form.Get("scene")       //scene
	if _, ok := variable.EntryBoxs[gameId]; !ok {
		utils.Error(consts.ErrUndefinedEntry, c)
		return
	}
	boxEntry := variable.EntryBoxs[gameId]
	loginInfo, err := service.CodeToUserInfo(code, &boxEntry)
	if err != nil {
		fmt.Printf("-----CodeToUserInfo err: %s", err)
		utils.Error(consts.ErrInvalidParams, c)
		return
	}
	if loginInfo.OpenId == "" {
		utils.Error(consts.ErrInvalidParams, c)
		return
	}
	user := model.GetUserByGameIdOpenId(gameId, loginInfo.OpenId)
	if user == nil { //新用户
		newUser := &model.User{
			UniqueId:    utils.GenUid(gameId, loginInfo.OpenId),
			MiniOpenId:  loginInfo.OpenId,
			MiniUnionId: loginInfo.UnionID,
			GameId:      gameId,
			ShareCode:   utils.GenUid(gameId+"_shareCode", loginInfo.OpenId),
		}
		if _, err := newUser.Insert(); err != nil {
			fmt.Printf("err %+v\n", err)
		} else {
			user = newUser
			extra := &model.UserExtra{
				UserId: newUser.Id,
				Coupon: 3,
			}
			if _, err = extra.Insert(); err != nil {
				fmt.Printf("-----UserExtra insert err: %s", err)
			}
		}
	}
	if loginInfo.OpenId == "" || encryptedData == "" || iv == "" {
		utils.Error(consts.ErrInvalidParams, c)
		return
	}
	newUserInfo, err := service.ParseUserInfo(loginInfo.OpenId, gameId, encryptedData, iv, nil, loginInfo.SessionKey)
	if err != nil {
		fmt.Printf("newUserInfo err: %+v\n", err)
		utils.Error(consts.ErrMiniOriData, c)
		return
	} else {
		user.City = newUserInfo.City
		user.Province = newUserInfo.Province
		user.HeadImgUrl = newUserInfo.AvatarURL
		user.Sex = newUserInfo.Gender
		user.NickName = base64.StdEncoding.EncodeToString([]byte(newUserInfo.NickName))
		user.HeadImgUpdatedAt = time.Now().Unix()
		user.MiniUnionId = newUserInfo.UnionID
		_, err := user.Update()
		if err != nil {
			fmt.Printf("-----PartySetUserInfo user update err: %s", err)
			utils.Error(consts.ErrUserUpadteFail, c)
			return
		}
	}
	reInt, shareStruct := service.ValidateShareToken(token)
	if reInt != 0 { //shareToken验证成功，用户通过其他用户的分享连接进入
		goods := model.GetGoodsById(shareStruct.GoodsId)
		if goods != nil { //分享新用户成功，获取抽奖券
			go func() {
				service.CreateInviteCoupon(shareStruct.UserId, goods)
			}()
		}
	} else { //shareToken验证失败
		if scene != "" { //scene不为空，用户通过二维码进入
			parentId = db.Mgo.GetUserIdFromScene(scene)
			if parentId != 0 {
				//判断是否有商品id，是否可以领取券码
				goodsId := db.Mgo.GetGoodsIdFromScene(scene)
				goods := model.GetGoodsById(goodsId)
				if goods != nil { //分享新用户成功，获取抽奖券
					go func() {
						service.CreateInviteCoupon(parentId, goods)
					}()
				}
			}
		}
	}
	resp := &RespUser{
		UniqueId:   user.UniqueId,
		OpenId:     loginInfo.OpenId,
		NickName:   utils.DecodeNickName(user.NickName),
		HeadImgUrl: user.HeadImgUrl,
	}
	utils.JSON(resp, c)
}

func Ping(c *gin.Context) {
	reInt, shareStruct := service.ValidateShareToken("f0c4d18951d17b9756b21bcc39f162ca")
	fmt.Printf("--------reInt %d\n, -------------shareStruct %v\n", reInt, shareStruct)
	fmt.Printf("ping %d\n", time.Now().Unix())
	utils.JSON("pong", c)
}

func ReadFileContent(c *gin.Context) {
	f, err := os.Open(FILE_PATH)
	if err != nil {
		fmt.Printf("ReadFileContent err %s", err)
	}
	defer f.Close()
	fContent, _ := ioutil.ReadAll(f)
	strContent := string(fContent)
	c.String(http.StatusOK, strContent)
}

func ReadNewFileContent(c *gin.Context) {
	f, err := os.Open(NEW_FILE_PATH)
	if err != nil {
		fmt.Printf("ReadFileContent err %s", err)
	}
	defer f.Close()
	fContent, _ := ioutil.ReadAll(f)
	strContent := string(fContent)
	c.String(http.StatusOK, strContent)
}

/**
获取用户弹窗提示信息
*/
func GetAlertInfo(c *gin.Context) {
	form := c.Request.Form
	uniqueId := form.Get("uniqueId")
	user := model.GetUserByUniqueId(uniqueId)
	if user == nil {
		utils.Error(consts.ErrUserNotFound, c)
		return
	}
	ret := make(map[string]interface{})
	var coins float64
	commonKey := "BoxKey::leyouboxgroupaccumkey_" + strconv.FormatInt(user.Id, 10)

	keyExist := db.MainRedisClient.Exists(commonKey)
	if keyExist.Val() == 1 {
		reVal := db.MainRedisClient.GetSet(commonKey, 0)
		coins, _ = strconv.ParseFloat(reVal.Val(), 64)
	} else {
		db.MainRedisClient.Set(commonKey, 0, time.Hour*24)
	}
	ret["coins"] = utils.Decimal(coins)
	ret["isAlert"] = 0
	if coins > 0 {
		ret["isAlert"] = 1
	}
	utils.JSON(ret, c)
}

func messageInfo(user *model.User, coins int, aType int64) map[string]interface{} {
	message := make(map[string]interface{})
	message["hasGroup"] = 1
	if aType == 1 {
		if coins > 0 {
			if coins < 200 {
				message["balance"] = strconv.FormatFloat(Decimal(float64(coins/1000)), 'f', -1, 64)
				message["lottery"] = 0
			} else {
				message["balance"] = strconv.FormatFloat(Decimal(float64(coins/1000)), 'f', -1, 64)
				message["lottery"] = coins / 1000
			}
		} else {
			userCount, _ := db.MysqlEngine.SQL("select count(*) from user_extra where parent_id = ?", user.Id).Count()
			if userCount == 0 {
				message["hasGroup"] = 0
			}
		}
	} else {
		if coins < 200 {
			message["balance"] = "还差" + strconv.Itoa(200-coins) + "金币可抽取红包"
		} else {
			if coins > 1000 {
				message["balance"] = "您的金币约值" + strconv.Itoa(coins/1000) + "元红包"
			} else {
				message["balance"] = "还差" + strconv.Itoa(1000-coins) + "金币可兑换1元金币"
			}
		}
	}
	return message
}

func Decimal(value float64) float64 {
	value, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", value), 64)
	return value
}

func GetLinks(c *gin.Context) {
	links, err := service.GetTutorialLinks()
	if err != nil {
		fmt.Printf("service.GetLinks err:", err)
	}
	utils.JSON(links, c)
}

/**
 @description 更新项目的盒子配置信息到全局变量中
 @return
 @author guxiang
 @version v1 2018-11-20
 */
func Reload(c *gin.Context) {
	err := variable.InitBox()
	if err != nil {
		utils.Error(consts.ErrUpdateEntryFail, c)
		return
	}
	utils.JSON("ok", c)
}

/**
 @description 获取收益中心数据
 @return mixed
 @author guxiang
 @version v1 2018-11-23
 */
func EarnCenter(c *gin.Context) {
	form := c.Request.Form
	uniqueId := form.Get("uniqueId")
	//gameId := form.Get("gameId")
	user := model.GetUserByUniqueId(uniqueId)
	if user == nil {
		utils.Error(consts.ErrUserNotFound, c)
		return
	}
	ret := make(map[string]interface{})
	//可提现收益
	uExtra := model.GetUserExtraByUid(user.Id)
	ret["balance"] = uExtra.Balance
	//累积收益
	ret["accum_balance"] = uExtra.AccumBalance
	//累积推广
	ret["accum_promote"] = uExtra.AccumPromote
	//已付费游戏
	//promote := service.GetPromoteGame(gameId, user.Id, 1)
	//ret["promote"] = promote
	//未付费游戏
	//unPromote := service.GetPromoteGame(gameId, user.Id, 0)
	//ret["unpromote"] = unPromote
	//已购买推广权数量
	//ret["promote_num"] = len(promote)
	//0元促销游戏
	//special := service.GetSpecialGames(gameId, user.Id)
	//ret["special"] = special
	//广告信息
	//advert := model.GetAdvertList(2)
	//ret["advert"] = advert
	//获取兑换物品信息
	goods, _ := service.GetGoodsList()
	ret["goods"] = goods

	utils.JSON(ret, c)
}

/**
 @description 获取收益中心，朋友体验详情
 @return []mgo.reward
 @author guxiang
 @version v1 2018-11-30
 */
func EarnFriends(c *gin.Context) {
	form := c.Request.Form
	uniqueId := form.Get("uniqueId")
	gameId := form.Get("gameId")
	user := model.GetUserByUniqueId(uniqueId)
	if user == nil {
		utils.Error(consts.ErrUserNotFound, c)
		return
	}
	rewardList := service.GetGameRewardList(user.Id, gameId)

	utils.JSON(rewardList, c)
}

/**
 @description 获取公司信息
 @return model.Company
 @author guxiang
 @version v1 2018-11-30
 */
func CompanyInfo(c *gin.Context) {
	company := model.GetCompanyInfo()
	utils.JSON(company, c)
}
